package com.tomtaw.web.callnumber.ui.home;


import static com.tomtaw.web.callnumber.MainActivity.DEBUG_MODEL;

import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.speech.tts.TextToSpeech;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


import android.webkit.WebSettings;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;


import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;


import com.elvishew.xlog.XLog;
import com.tomtaw.web.callnumber.MainActivity;
import com.tomtaw.web.callnumber.R;
import com.tomtaw.web.callnumber.StringUtil;
import com.tomtaw.web.callnumber.storage.AppPrefs;

import org.xwalk.core.XWalkSettings;
import org.xwalk.core.XWalkView;

import java.util.Locale;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class HomeFragment extends Fragment implements IFragmentView {

    private HomeViewModel homeViewModel;
    public XWalkView mWebView;
    private TextToSpeech mTTS;
    private WebJsManager mWebJsManager;
    private MediaPlayer mPlayer;


    private BlockingQueue<String> mQueue = new LinkedBlockingQueue<String>(1024);
    private boolean mIsPlay = false;
    Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                if (mIsPlay) {
                    return;
                }
                mIsPlay = true;
                final String audioUrl = mQueue.poll(1, TimeUnit.SECONDS);
                if (mPlayer != null) {
                    mPlayer.stop();
                    mPlayer.reset();
                    mPlayer.release();
                    mPlayer = null;
                }
                if (null != audioUrl) {
                    mPlayer = new MediaPlayer();
                    mPlayer.setDataSource(audioUrl);
                    mPlayer.prepareAsync();
                    //mPlayer.start();
                    mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            XLog.i("开始播放音频");
                            mp.start();
                        }
                    });

                    mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                        @Override
                        public boolean onError(MediaPlayer mp, int what, int extra) {
                            XLog.e("播放错误：" + audioUrl + ",错误码:" + what + "," + extra);
                            mIsPlay = false;
                            mWebView.postDelayed(mRunnable, 100);
                            return true;
                        }
                    });
                    mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            mIsPlay = false;
                            mWebView.postDelayed(mRunnable, 200);
                        }
                    });
                } else {
                    mIsPlay = false;
                    XLog.e("音频队列为空，未获取到音频URL");

                }

            } catch (InterruptedException e) {
                mIsPlay = false;
                XLog.e(e.getMessage());

            } catch (Exception e) {
                mIsPlay = false;
                XLog.e(e.getMessage());
            }
        }
    };

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        homeViewModel =
                ViewModelProviders.of(getActivity()).get(HomeViewModel.class);
        View root = inflater.inflate(R.layout.fragment_home, container, false);
        final LinearLayout mWebViewLayout = root.findViewById(R.id.web_view_layout);

        mWebView = new XWalkView(getActivity());
        initSettings();


        mWebView.setUIClient(new XWUIClient(mWebView, getActivity()));
        mWebView.setResourceClient(new XWResourceClient(mWebView));

        // XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);

        mWebJsManager = new WebJsManager(this);
        mWebView.addJavascriptInterface(mWebJsManager, "AndroidApp");


        mWebViewLayout.addView(mWebView);
        mWebView.clearCache(true);


        homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                mWebView.loadUrl(s);
            }
        });


        // 参数Context,TextToSpeech.OnInitListener
        mTTS = new TextToSpeech(getContext(), new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status == TextToSpeech.SUCCESS) {

                    // setLanguage设置语言
                    int result = mTTS.setLanguage(Locale.CHINA);
                    // int result2 = mTTS.setLanguage(Locale.CHINESE);
                    // TextToSpeech.LANG_MISSING_DATA：表示语言的数据丢失
                    // TextToSpeech.LANG_NOT_SUPPORTED：不支持
                    if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                        Toast.makeText(getActivity(), "中文语料包数据丢失或不支持", Toast.LENGTH_SHORT).show();
                        //不支持中文就将语言设置为英文
                        mTTS.setLanguage(Locale.US);
                    }

                    if (mTTS != null) {
                        // 设置音调，值越大声音越尖（女生），值越小则变成男声,1.0是常规
                        mTTS.setPitch(1.0f);
                        // 设置语速
                        //        tts.setSpeechRate(0.5f);
                    }

                    mWebView.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            mWebJsManager.playTTS("语音设备检测结果正常。");
                        }
                    }, 5000);

                }
            }
        });

        return root;
    }


    /**
     * 没有允许定位的设置
     */
    private void initSettings() {
        XWalkSettings webSettings = mWebView.getSettings();

        //启用JavaScript
        webSettings.setJavaScriptEnabled(true);
        //允许js弹窗alert等，window.open方法打开新的网页，默认不允许
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);


        //localStorage和sessionStorage
        webSettings.setDomStorageEnabled(true);
        //Web SQL Databases
        webSettings.setDatabaseEnabled(true);
        //是否可访问Content Provider的资源，默认值 true
        webSettings.setAllowContentAccess(true);

        /*
        是否允许访问文件系统，默认值 true
        file:///androMSG_asset和file:///androMSG_res始终可以访问，不受其影响
         */
        webSettings.setAllowFileAccess(true);
        //是否允许通过file url加载的Javascript读取本地文件，默认值 false
        webSettings.setAllowFileAccessFromFileURLs(true);
        //是否允许通过file url加载的Javascript读取全部资源(包括文件,http,https)，默认值 false
        webSettings.setAllowUniversalAccessFromFileURLs(true);

        //设置是否支持缩放
        webSettings.setSupportZoom(false);
        //设置内置的缩放控件
        webSettings.setBuiltInZoomControls(false);

        /*
         当该属性被设置为false时，加载页面的宽度总是适应WebView控件宽度；
         当被设置为true，当前页面包含viewport属性标签，在标签中指定宽度值生效，如果页面不包含viewport标签，无法提供一个宽度值，这个时候该方法将被使用。
         */
        webSettings.setUseWideViewPort(false);
        //缩放至屏幕大小
        webSettings.setLoadWithOverviewMode(true);
        //支持多窗口
        webSettings.setSupportMultipleWindows(true);

        /*
        缓存模式
        LOAD_CACHE_ONLY         不使用网络，只读取本地缓存
        LOAD_DEFAULT            根据cache-control决定是否从网络上获取数据
        LOAD_NO_CACHE           不使用缓存，只从网络获取数据
        LOAD_CACHE_ELSE_NETWORK 只要本地有，无论是否过期，或者no-cache，都使用缓存中的数据
         */
        webSettings.setCacheMode(XWalkSettings.LOAD_NO_CACHE);
        //设置是否加载图片
        webSettings.setLoadsImagesAutomatically(true);

    }


    @Override
    public void onDestroyView() {
        if (mPlayer != null) {
            mPlayer.stop();
            mPlayer.reset();
            mPlayer.release();
            mPlayer = null;
        }

        if (mTTS != null) {
            mTTS.stop();
            mTTS.shutdown();
            mTTS = null;
        }

        super.onDestroyView();
    }


    @Override
    public void playTTS(final String tts) {
        // validate
        if (StringUtil.isBlank(tts)) {
            Toast.makeText(getActivity(), "请您输入要朗读的文字", Toast.LENGTH_SHORT).show();
            return;
        }


        if (mTTS != null && !mTTS.isSpeaking()) {
            //   Toast.makeText(getActivity(), "即将播报："+tts, Toast.LENGTH_SHORT).show();
            /*
                TextToSpeech的speak方法有两个重载。
                // 执行朗读的方法
                speak(CharSequence text,int queueMode,Bundle params,String utteranceId);
                // 将朗读的的声音记录成音频文件
                synthesizeToFile(CharSequence text,Bundle params,File file,String utteranceId);
                第二个参数queueMode用于指定发音队列模式，两种模式选择
                （1）TextToSpeech.QUEUE_FLUSH：该模式下在有新任务时候会清除当前语音任务，执行新的语音任务
                （2）TextToSpeech.QUEUE_ADD：该模式下会把新的语音任务放到语音任务之后，
                等前面的语音任务执行完了才会执行新的语音任务
             */


            mWebView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mTTS.speak(tts, TextToSpeech.QUEUE_FLUSH, null);
                }
            }, 2000);


        }
    }

    @Override
    public void playAudio(String audioUrl) {

        XLog.tag("HomeFragment").i("playAudio语音地址:" + audioUrl);

        try {
            if (!mQueue.offer(audioUrl, 2, TimeUnit.SECONDS)) {
                XLog.e(audioUrl + "添加待播放队列失败");
            } else {
                XLog.e(audioUrl + "添加待播放队列成功");
                if (!mIsPlay) {
                    mWebView.postDelayed(mRunnable, 500);
                } else {
                    //播放线程出问题无释放，预防待播放URL队列溢出
                    if (mQueue.size() >= 30){
                        mIsPlay = false;
                    }
                    XLog.i("有语音正在播放中。禁止推送：" + audioUrl);
                }
            }
        } catch (InterruptedException e) {
            XLog.e(e.getMessage());
        }catch (Exception e) {
            XLog.e(e.getMessage());
        }

//        try {
//            if (mPlayer != null){
//                mPlayer.stop();
//                mPlayer.reset();
//                mPlayer.release();
//                mPlayer = null;
//            }
//
//            mPlayer =  new MediaPlayer();
//            mPlayer.setDataSource(audioUrl);
//            mPlayer.prepare();
//            mPlayer.start();
//        } catch (Exception e) {
//            XLog.e(e.getMessage());
//        }
    }
}